#ifndef _HEROS_H_
#define _HEROS_H_

#include "Terrain.h"
#include "ArmeSecondaire.h"
#include "ArmePrincipale.h"


/** @brief File brief description
    Le fichier Heros.h contient la declaration de toutes les fonctions et procedures necessaires
    à la gestion du heros de notre jeu (creation, deplacement, changements 
    de ses caracteristiques a cause d'une action exterieure (par exemple perte de vie si touche
    par un tir ou gain si ramassage d'un bonus) et destruction*/


/** @brief Un heros possede une arme principale, 2 armes secondaires, de la vie (un entier), une position
 *  definie par 2 reels et une taille suivant chacun des axes X et Y (2 reels)*/
typedef struct
{
	ArmePrincipale* parme_principale;
	ArmeSecondaire* parme_secondaire1;
	ArmeSecondaire* parme_secondaire2;
	int vie_heros;	
	float posX_heros;
	float posY_heros;
	float tailleX_heros;
	float tailleY_heros;
	
} Heros;

/** @brief  Cette procedure initialise un heros à l'aide de valeurs passées en paramètres
    @param [in,out] parm_prin
    @param [in,out] parm_sec_1
    @param [in,out] parm_sec_2
    @param [in] vie
    @param [in] posX
    @param [in] posY
    @param [in] tailleX
    @param [in] tailleY
    @return none*/
void initHeros (Heros* pheros, ArmePrincipale* parm_prin,
ArmeSecondaire* parm_sec1, ArmeSecondaire* parm_sec2, const int vie,
const float posX, const float posY, const float tailleX, const float tailleY);


/** @brief Cette procedure libère l'espace memoire alloué dans le tas pour les armes d'un heros
 *  @param [in,out] pheros
    @return none*/
void libereHeros (Heros* pheros);


/** @brief Cette fonction  réserve dans le tas l'espace nécessaire pour un heros,
 *  l'initialise et retourne un pointeur sur le heros créé
 *  @param [in,out] parm_prin
    @param [in,out] parm_sec_1
    @param [in,out] parm_sec_2
    @param [in] vie
    @param [in] posX
    @param [in] posY
    @param [in] tailleX
    @param [in] tailleY
    @return Heros* pheros*/
Heros* creerHeros (ArmePrincipale* parm_prin,ArmeSecondaire* parm_sec1, 
ArmeSecondaire* parm_sec2, const float vie,const float posX, const float posY,
const float tailleX, const float tailleY);


/** @brief Cette procedure libère l'espace memoire alloué dans le tas pour un heros
 *  @param [in,out] pheros
    @return none*/
void detruireHeros (Heros** ppheros);


/** @brief Cette fonction retourne un pointeur sur l'arme principale du heros
 *  @param [in] pheros
    @return ArmeSecondaire* arme_principale*/
ArmePrincipale* getArmePrincipale (const Heros* pheros);


/** @brief Cette fonction retourne un pointeur sur l'arme secondaire 1 du heros
 *  @param [in] pheros
    @return ArmeSecondaire* arme_secondaire1*/
ArmeSecondaire* getArmeSecondaire1 (const Heros* pheros);


/** @brief Cette fonction retourne un pointeur sur l'arme secondaire 2 du heros
 *  @param [in] pheros
    @return ArmeSecondaire* arme_secondaire2*/
ArmeSecondaire* getArmeSecondaire2 (const Heros* pheros);


/** @brief Cette fonction retourne un entier correspondant aux points de vie restants 
 *  du heros passé en paramètre
 *  @param [in] pheros
    @return vie_heros*/
const int getVieHeros (const Heros* pheros);


/** @brief Cette procédure remplace la vie du heros passé en paramètre par une valeur
    passée en paramètre
 *  @param [in,out] pheros
    @param [in] vie
    @return none*/
void setVieHeros (Heros* pheros, const int vie);


/** @brief Cette fonction retourne un réel correspondant à la position suivant l'axe des abscisses 
 *  du heros passé en paramètre
 *  @param [in] pheros
    @return posX_heros*/
const float getPosXHeros (const Heros* pheros);


/** @brief Cette procédure remplace la position suivant l'axe des abscisses du heros passé en paramètre par une valeur
 passée en paramètre
 *  @param [in,out] pheros
    @param [in] posX
    @return none*/
void setPosXHeros (Heros* pheros, const float posX_heros);


/** @brief Cette fonction retourne un réel correspondant à la position suivant l'axe des ordonnées 
 *du heros passé en paramètre
 *  @param [in] pheros
    @return posY_heros*/
const float getPosYHeros (const Heros* pheros);


/** @brief Cette procédure remplace la position suivant l'axe des ordonnées du heros passé en paramètre par une valeur
 passée en paramètre
 *  @param [in,out] pheros
    @param [in] posY
    @return none*/
void setPosYHeros (Heros* pheros, const float posY_heros);


/** @brief Cette fonction retourne un réel correspondant à la taille suivant l'axe des abscisses 
 *du heros passé en paramètre
 *  @param [in] pheros
    @return tailleX_heros*/
const float getTailleXHeros (const Heros* pheros);


/** @brief Cette procédure remplace la taille suivant l'axe des abscisses du heros passé en paramètre par une valeur
 passée en paramètre
 *  @param [in,out] pheros
    @param [in] tailleX
    @return none*/
void setTailleXHeros (Heros* pheros, const float tailleX_heros);


/** @brief Cette fonction retourne un réel correspondant à la position suivant l'axe des ordonnées 
 *du heros passé en paramètre
 *  @param [in] pheros
    @return tailleY_heros*/
const float getTailleYHeros (const Heros* pheros);


/** @brief Cette procédure remplace la position suivant l'axe des ordonnées du heros passé en paramètre par une valeur
 passée en paramètre
 *  @param [in,out] pheros
    @param [in] tailleY
    @return none*/
void setTailleYHeros (Heros* pheros, const float tailleY_heros);


/** @brief Cette fonction renvoie un pointeur sur un tir de l'arme principale (canon 1) du heros passé en paramètre
 * lors d'un tir vertical de cette arme.
 *  @param [in,out] pheros
    @return Tir* ptir*/
Tir* tirerHeros (Heros* pheros);


/** @brief Cette fonction renvoie un pointeur sur un tir de l'arme principale (canon 2) du heros passé en paramètre
 * lors d'un tir vertical de cette arme.
 *  @param [in,out] pheros
    @return Tir* ptir*/
Tir* tirerHeros2 (Heros* pheros);


/** @brief Cette fonction renvoie un pointeur sur un tir de l'arme principale (canon 1) du heros passé en paramètre
 * lors d'un tir oblique à grande distance.
 *  @param [in,out] pheros
 *  @param [in,out] pterrain
    @return Tir* ptir*/
Tir* tirerHerosObliqueGaucheHaut (Heros* pheros, Terrain* pterrain);


/** @brief Cette fonction renvoie un pointeur sur un tir de l'arme principale (canon 4) du heros passé en paramètre
 * lors d'un tir oblique à grande distance.
 *  @param [in,out] pheros
 *  @param [in,out] pterrain
    @return Tir* ptir*/
Tir* tirerHerosObliqueDroiteHaut (Heros* pheros, Terrain* pterrain);


/** @brief Cette fonction renvoie un pointeur sur un tir de l'arme principale (canon 1) du heros passé en paramètre
 * lors d'un tir oblique à moyenne distance.
 *  @param [in,out] pheros
 *  @param [in,out] pterrain
    @return Tir* ptir*/
Tir* tirerHerosObliqueGaucheMilieu (Heros* pheros, Terrain* pterrain);


/** @brief Cette fonction renvoie un pointeur sur un tir de l'arme principale (canon 4) du heros passé en paramètre
 * lors d'un tir oblique à moyenne distance .
 *  @param [in,out] pheros
 *  @param [in,out] pterrain
    @return Tir* ptir*/
Tir* tirerHerosObliqueDroiteMilieu (Heros* pheros, Terrain* pterrain);


/** @brief Cette fonction renvoie un pointeur sur un tir de l'arme secondaire 1 du heros passé en paramètre
 *  @param [in,out] pheros
    @return Tir* ptir*/
Tir* tirerHerosS1 (Heros* pheros);


/** @brief Cette fonction renvoie un pointeur sur un tir de l'arme secondaire 2 du heros passé en paramètre
 *  @param [in,out] pheros
    @return Tir* ptir*/
Tir* tirerHerosS2 (Heros* pheros);

/** @brief Cette procedure diminue la vie du heros passé en paramètre en enlevant à la vie actuelle l'entier
 * passé en paramètre
 *  @param [in,out] pheros
 *  @param [in] vie_moins
 *  @return none*/
void enleverVie (Heros* pheros, int vie_moins);


/** @brief Cette fonction renvoie un entier indiquant si la position du heros passé en paramètre est valide après déplacement 
 *  sur un terrain eux aussi passés en paramètres
 *  @param [in,out] pterrain
 *  @param [in] pheros
 *  @param [in] deplacementX
 *  @param [in] deplacementY
    @return est_valide*/
const int terEstPositionHerosValide (const Terrain* pterrain,Heros* pheros, 
const float deplacementX, const float deplacementY);
	

/** @brief Cette procedure déplace vers la droite le heros passé en paramètre sur un terrain lui aussi passé en paramètre
 *  @param [in,out] pheros
 *  @param [in,out] pterrain
 *  @return none*/
void deplacerHerosDroite (Heros* pheros, Terrain* pterrain);


/** @brief Cette procedure déplace vers la gauche le heros passé en paramètre sur un terrain lui aussi passé en paramètre
 *  @param [in,out] pheros
 *  @param [in,out] pterrain
 *  @return none*/
void deplacerHerosGauche (Heros* pheros, Terrain* pterrain);


/** @brief Cette procedure déplace vers le haut le heros passé en paramètre sur un terrain lui aussi passé en paramètre
 *  @param [in,out] pheros
 *  @param [in,out] pterrain
 *  @return none*/
void deplacerHerosHaut (Heros* pheros, Terrain* pterrain);


/** @brief Cette procedure déplace vers le bas le heros passé en paramètre sur un terrain lui aussi passé en paramètre
 *  @param [in,out] pheros
 *  @param [in,out] pterrain
 *  @return none*/
void deplacerHerosBas (Heros* pheros, Terrain* pterrain);


#endif
